package com.atguigu.product.products.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.exception.enumtion.ProductUpEnum;
import com.atguigu.common.to.es.AttrTo;
import com.atguigu.common.to.es.SkuHasStock;
import com.atguigu.common.to.es.SpuUpTo;
import com.atguigu.common.utils.R;
import com.atguigu.product.products.dao.*;
import com.atguigu.product.products.entity.*;
import com.atguigu.product.products.feign.CouponFeign;
import com.atguigu.product.products.feign.SearchFeign;
import com.atguigu.product.products.feign.WareFeign;
import com.atguigu.product.products.service.*;
import com.atguigu.product.products.to.SkuFullReductionTo;
import com.atguigu.product.products.to.SpuBoundsTo;
import com.atguigu.product.products.vo.respVo.OrderToProductQuerySpuInfoVo;
import com.atguigu.product.products.vo.respVo.SpuSaveVo.SpuSaveReqVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import org.springframework.transaction.annotation.Transactional;


@Service("pmsSpuInfoService")
public class PmsSpuInfoServiceImpl extends ServiceImpl<PmsSpuInfoDao, PmsSpuInfoEntity> implements PmsSpuInfoService {

    @Autowired
    private PmsSpuInfoDescDao pmsSpuInfoDescDao;
    @Autowired
    private PmsSpuImagesService imagesService;
    @Autowired
    private PmsAttrDao pmsAttrDao;
    @Autowired
    private PmsProductAttrValueService pmsProductAttrValueService;

    @Autowired
    private PmsSkuInfoService pmsSkuInfoService;

    @Autowired
    private PmsSkuImagesService skuImagesService;
    @Autowired
    private PmsSkuSaleAttrValueService pmsSkuSaleAttrValueService;

    @Autowired
    private CouponFeign couponFeign;
    @Autowired
    private PmsBrandDao pmsBrandDao;

    @Autowired
    private PmsCategoryDao pmsCategoryDao;


    @Autowired
    private WareFeign wareFeign;

    @Autowired
    private SearchFeign searchFeign;


    /**
     * 远程调用-根据skuId查询对应的spu信息
     * @param skuId
     * @return
     */
    public OrderToProductQuerySpuInfoVo orderSpu(Long skuId) {
        OrderToProductQuerySpuInfoVo orderToProductQuerySpuInfoVo=new OrderToProductQuerySpuInfoVo();
        PmsSkuInfoEntity skuInfoEntity = pmsSkuInfoService.getBaseMapper().selectById(skuId);
        orderToProductQuerySpuInfoVo.setCategoryId(skuInfoEntity.getCatalogId());
        orderToProductQuerySpuInfoVo.setSpuId(skuInfoEntity.getSpuId());
        orderToProductQuerySpuInfoVo.setSkuPrice(skuInfoEntity.getPrice());
        //根据spuId获取对应的图片以及对应的名称
        PmsSpuInfoEntity pmsSpuInfoEntity = this.baseMapper.selectById(skuInfoEntity.getSpuId());
        orderToProductQuerySpuInfoVo.setSpuPic(pmsSpuInfoEntity.getSpuDescription());
        orderToProductQuerySpuInfoVo.setSpuName(pmsSpuInfoEntity.getSpuName());
        //根据品牌获取品牌名称
        PmsBrandEntity pmsBrandEntity = pmsBrandDao.selectById(skuInfoEntity.getBrandId());
        orderToProductQuerySpuInfoVo.setSpuBrand(pmsBrandEntity.getName());
        return orderToProductQuerySpuInfoVo;
    }



    /**
     * 商品上架
     * @param spuId
     * @return
     */
    @Transactional
    public void up(Long spuId) {
        /**
         * skuPrice,skuImg,hasStock
         *
         *
         * attrs：
         * attrId
         * attrName
         * attrValue
         */



        //根据spuid查询出所有的sku商品
        List<PmsSkuInfoEntity> pmsSkuInfoEntities = pmsSkuInfoService.list(new QueryWrapper<PmsSkuInfoEntity>().eq("spu_id", spuId));
        //根据品牌id查询名称以及默认图片
        PmsBrandEntity pmsBrandEntity = pmsBrandDao.selectById(pmsSkuInfoEntities.get(0).getBrandId());
        //根据分类id查询分类名称
        PmsCategoryEntity pmsCategoryEntity = pmsCategoryDao.selectById(pmsSkuInfoEntities.get(0).getCatalogId());
        //查询符合条件的规格参数
        List<PmsProductAttrValueEntity> pmsProductAttrValueEntities = pmsProductAttrValueService.list(new QueryWrapper<PmsProductAttrValueEntity>().eq("spu_id", spuId));
        List<Long> attrIds = pmsProductAttrValueEntities.stream().map(m -> m.getAttrId()).collect(Collectors.toList());
        List<PmsAttrEntity> pmsAttrEntities = pmsAttrDao.selectList(new QueryWrapper<PmsAttrEntity>().in("attr_id", attrIds).eq("search_type", 1));
        List<Long> longList = pmsAttrEntities.stream().map(m1 -> m1.getAttrId()).collect(Collectors.toList());
        List<AttrTo> attrTos = pmsProductAttrValueEntities.stream().filter(m ->
                longList.contains(m.getAttrId()
                )).map((m) -> {
            AttrTo attrTo = new AttrTo();
            BeanUtils.copyProperties(m, attrTo);
            return attrTo;
        }).collect(Collectors.toList());
        List<SkuHasStock> skuHasStocks=null;


        try{
            // TODO 远程调用查看是否存在库存
            R r = wareFeign.skuIdInfo(pmsSkuInfoEntities.stream().map(PmsSkuInfoEntity::getSkuId).collect(Collectors.toList()));
            skuHasStocks = r.getData(new TypeReference<List<SkuHasStock>>() {
            });
        }catch (Exception e){
            log.error("库存服务查询异常:原因{}",e);
        }


        Map<Long, Integer> map = skuHasStocks.stream().collect(Collectors.toMap(SkuHasStock::getSkuId, SkuHasStock::getHasStock));


        List<SpuUpTo> spuUpTos = pmsSkuInfoEntities.stream().map((m) -> {
            SpuUpTo spuUpTo = new SpuUpTo();
            BeanUtils.copyProperties(m, spuUpTo);
            spuUpTo.setBrandImg(pmsBrandEntity.getLogo()==null?null:pmsBrandEntity.getLogo());
            spuUpTo.setBrandName(pmsBrandEntity.getName());
            spuUpTo.setCatalogName(pmsCategoryEntity.getName());
            spuUpTo.setSkuImg(m.getSkuDefaultImg());
            spuUpTo.setSkuPrice(m.getPrice());
            //TODO 设置热度评分
            spuUpTo.setHotScore(new BigDecimal(0));
            if(map.get(m.getSkuId())==null){
                spuUpTo.setHasStock(false);
            }else {
                spuUpTo.setHasStock(map.get(m.getSkuId())>0?true:false);
            }

            //设置规格参数属性
            spuUpTo.setAttrs(attrTos);
            return spuUpTo;

        }).collect(Collectors.toList());
        //TODO 来将数据保存到es中
        searchFeign.searchSave(spuUpTos);

        //上架成功修改对应spu表中的状态为已上架
        PmsSpuInfoEntity pmsSpuInfoEntity=new PmsSpuInfoEntity();
        pmsSpuInfoEntity.setId(spuId);
        pmsSpuInfoEntity.setPublishStatus(ProductUpEnum.PRODUCT_UP.getCode());
        pmsSpuInfoEntity.setUpdateTime(new Date());
        this.updateById(pmsSpuInfoEntity);
    }



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PmsSpuInfoEntity> page = this.page(
                new Query<PmsSpuInfoEntity>().getPage(params),
                new QueryWrapper<PmsSpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 保存商品信息
     *
     * @param spuSaveReqVo
     */

    // TODO ①远程调用出现问题如何处理 ②分布式事务的解决  ③保存有没必要数据
   @Transactional
    public void saveDetail(SpuSaveReqVo spuSaveReqVo) {
        //保存商品基本信息到spu表中
        PmsSpuInfoEntity spuInfoEntity = new PmsSpuInfoEntity();
        BeanUtils.copyProperties(spuSaveReqVo, spuInfoEntity);
    //新增商品表
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        this.save(spuInfoEntity);
        List<String> decript = spuSaveReqVo.getDecript();
        //逗号组装数据
        String decripts = String.join(",", decript);
     //新增商品到商品描述表
        PmsSpuInfoDescEntity ens = new PmsSpuInfoDescEntity();
        ens.setSpuId(spuInfoEntity.getId());
        ens.setDecript(decripts);
        pmsSpuInfoDescDao.insert(ens);


     //新增数据到spu图片表
        List<PmsSpuImagesEntity> imagesEntityList = spuSaveReqVo.getImages().stream().map((m) -> {
            PmsSpuImagesEntity imagesEntity = new PmsSpuImagesEntity();
            imagesEntity.setImgUrl(m);
            imagesEntity.setSpuId(spuInfoEntity.getId());
            return imagesEntity;
        }).collect(Collectors.toList());
        imagesService.saveBatch(imagesEntityList);

     //远程服务保存商品spu积分设置
        SpuBoundsTo  spuBoundsTo=new SpuBoundsTo();
        if(spuSaveReqVo.getBounds()!=null){
            BeanUtils.copyProperties(spuSaveReqVo.getBounds(),spuBoundsTo);
            spuBoundsTo.setSpuId(spuInfoEntity.getId());
            couponFeign.save(spuBoundsTo);

        }




     //新增数据到spu属性值表中
        List<PmsProductAttrValueEntity> productAttrValueEntities = spuSaveReqVo.getBaseAttrs().stream().map((m) -> {
            PmsProductAttrValueEntity valueEntity = new PmsProductAttrValueEntity();
            BeanUtils.copyProperties(m, valueEntity);
            valueEntity.setAttrValue(m.getAttrValues());
            valueEntity.setAttrSort(0);
            valueEntity.setSpuId(spuInfoEntity.getId());
            valueEntity.setQuickShow(m.getShowDesc());
            return valueEntity;

        }).collect(Collectors.toList());

        List<Long> attrIds1 = spuSaveReqVo.getBaseAttrs().stream().map(m1 -> m1.getAttrId()).collect(Collectors.toList());
        //根据属性id查询所有的属性
        List<PmsAttrEntity> pmsAttrEntities = pmsAttrDao.selectList(new QueryWrapper<PmsAttrEntity>().in("attr_id", attrIds1));
        //将属性名称赋值给spu属性值表
        List<PmsProductAttrValueEntity> pmsProductAttrValueEntities = productAttrValueEntities.stream().map((m) -> {
            List<PmsAttrEntity> entities = pmsAttrEntities.stream().filter(m1 -> m1.getAttrId().equals(m.getAttrId())).collect(Collectors.toList());
            m.setAttrName(entities.get(0).getAttrName());
            return m;
        }).collect(Collectors.toList());
     //批量新增到spu属性值中
        pmsProductAttrValueService.saveBatch(pmsProductAttrValueEntities);



    //新增到sku基本属性中
        //保存默认图片图片
        List<String> images=new ArrayList<>();
          spuSaveReqVo.getSkus().stream().forEach((m) -> {
            PmsSkuInfoEntity pmsSkuInfoEntity = new PmsSkuInfoEntity();
            BeanUtils.copyProperties(m, pmsSkuInfoEntity);
            if (m.getImages() != null) {
                m.getImages().forEach((m1) -> {
                    if (m1.getDefaultImg() == 1) {
                        images.add(m1.getImgUrl());
                    }
                });

                //逗号分割
                String imagess = String.join(",", images);
                pmsSkuInfoEntity.setSkuDefaultImg(imagess);
                pmsSkuInfoEntity.setSpuId(spuInfoEntity.getId());
                pmsSkuInfoEntity.setBrandId(spuSaveReqVo.getBrandId());
                pmsSkuInfoEntity.setCatalogId(spuSaveReqVo.getCatalogId());
                //将集合清空
                images.clear();
            }
     //调用新增方法保存sku信息
              pmsSkuInfoService.save(pmsSkuInfoEntity);
            //可以获取sku_id,保存到pms_sku_images中
              List<PmsSkuImagesEntity> pmsSkuImagesEntities = m.getImages().stream().map((m2) -> {
                  PmsSkuImagesEntity skuImagesEntity = new PmsSkuImagesEntity();
                  BeanUtils.copyProperties(m2, skuImagesEntity);
                  skuImagesEntity.setSkuId(pmsSkuInfoEntity.getSkuId());
                  skuImagesEntity.setImgSort(0);
                  return skuImagesEntity;
              }).collect(Collectors.toList());
     //保存sku图片信息
              skuImagesService.saveBatch(pmsSkuImagesEntities);


              //需要保存属性关联表 pms_sku_sale_attr_value
              List<PmsSkuSaleAttrValueEntity> pmsSkuSaleAttrValueEntities = m.getAttr().stream().map((m3) -> {
                  PmsSkuSaleAttrValueEntity skuSaleAttrValueEntity = new PmsSkuSaleAttrValueEntity();
                  BeanUtils.copyProperties(m3, skuSaleAttrValueEntity);
                  skuSaleAttrValueEntity.setAttrSort(0);
                  skuSaleAttrValueEntity.setSkuId(pmsSkuInfoEntity.getSkuId());
                  return skuSaleAttrValueEntity;
              }).collect(Collectors.toList());
     //sku销售属性
              pmsSkuSaleAttrValueService.saveBatch(pmsSkuSaleAttrValueEntities);


              //远程调用优惠信息保存商品满减信息
              SkuFullReductionTo skuFullReductionTo=new SkuFullReductionTo();
              BeanUtils.copyProperties(m,skuFullReductionTo);
              skuFullReductionTo.setSkuId(pmsSkuInfoEntity.getSkuId());
               //远程服务商品满减信息
              couponFeign.save(skuFullReductionTo);


          });



    }


}